import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { Context } from '@midwayjs/koa';
import { ArticlesEntity } from '../entity/articles';
import { UserEntity } from '../entity/user';
import { DictInfoService } from '../../dict/service/info';
import { ArticleLikesEntity } from '../entity/article_likes';
import { CommentsEntity } from '../entity/comments';

/**
 * 文章
 */
@Provide()
export class ArticlesService extends BaseService {
    @Inject()
    ctx: Context;

    @InjectEntityModel(UserEntity)
    userEntity: Repository<UserEntity>;

    @InjectEntityModel(DictInfoService)
    dictInfoService: DictInfoService;

    @InjectEntityModel(ArticlesEntity)
    articlesEntity: Repository<ArticlesEntity>;

    @InjectEntityModel(ArticleLikesEntity)
    articleLikesEntity: Repository<ArticleLikesEntity>;

    @InjectEntityModel(CommentsEntity)
    commentsEntity: Repository<CommentsEntity>;

    /**
     * 发布文章
     * @param content 内容
     * @param images 图片
     * @param circleId 圈子
     * @param tagIds 标签
     */
    async publish(content, images, circleId, tagIds) {
        try {
            images = images.length ? images.join(',') : '';
            tagIds = tagIds.join(',');
            const userId = this.ctx.user.userId;
            const publish = await this.articlesEntity.save({ content, images, circleId, tagIds, userId });
            if (publish) {
                return {
                    success: true,
                    message: '发布成功',
                    data: null
                }
            }
            return {
                success: false,
                message: '发布失败',
                data: null
            }
        } catch (error) {
            console.log(error);
            throw new CoolCommException('发布失败');
        }
    }

    /**
     * 主页文章列表
     * @param page 页码
     * @param size 条数
     * @param type 类型 0最新 1最热
     */
    async indexList(page, size, type) {
        try {
            const sql = `
                SELECT
                a.*,
                u.avatar,
                u.nickname,
                u.sex,
                GROUP_CONCAT( d.name ) AS tags,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_article_likes al
                    WHERE
                        al.articleId = a.id
                ) AS likes,
                (
                    SELECT
                        GROUP_CONCAT( u.avatar )
                    FROM
                        app_article_likes al
                        LEFT JOIN app_user u ON al.userId = u.id
                    WHERE
                        al.articleId = a.id
                    ORDER BY
                        al.createTime DESC
                    LIMIT 4
                ) AS likesAvatar,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_comments ac
                    WHERE
                        ac.articleId = a.id
                ) AS comments
            FROM
                app_articles a
                LEFT JOIN app_user u ON a.userId = u.id
                LEFT JOIN dict_info d ON FIND_IN_SET( d.id, a.tagIds )
            WHERE
                a.status = 1
            GROUP BY
                a.id
            ORDER BY
                ${type == 0 ? 'a.createTime' : 'a.views'} DESC
            LIMIT ${(page - 1) * size}, ${size}
            `;
            const list = await this.articlesEntity.query(sql);
            list.map(item => {
                item.images = item.images.length ? item.images.split(',') : [];
                item.tags = item.tags.split(',');
                item.createTime = new Date(item.createTime).getTime();
                item.likesAvatar = item.likesAvatar ? item.likesAvatar.split(',') : [];
                return item;
            });
            return {
                success: true,
                message: '查询成功',
                data: list
            }
        } catch (error) {
            throw new CoolCommException('查询失败');
        }
    }

    /**
     * 圈子文章列表
     * @param circleId 圈子id
     * @param page 页码
     * @param size 条数
     */
    async circleList(circleId, page, size) {
        try {
            const sql = `
                SELECT
                a.*,
                u.avatar,
                u.nickname,
                u.sex,
                GROUP_CONCAT( d.name ) AS tags,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_article_likes al
                    WHERE
                        al.articleId = a.id
                ) AS likes,
                (
                    SELECT
                        GROUP_CONCAT( u.avatar )
                    FROM
                        app_article_likes al
                        LEFT JOIN app_user u ON al.userId = u.id
                    WHERE
                        al.articleId = a.id
                    ORDER BY
                        al.createTime DESC
                    LIMIT 4
                ) AS likesAvatar,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_comments ac
                    WHERE
                        ac.articleId = a.id
                ) AS comments
            FROM
                app_articles a
                LEFT JOIN app_user u ON a.userId = u.id
                LEFT JOIN dict_info d ON FIND_IN_SET( d.id, a.tagIds )
            WHERE
                a.circleId = ${circleId}
                AND a.status = 1
            GROUP BY
                a.id
            ORDER BY
                a.createTime DESC
            LIMIT ${(page - 1) * size}, ${size}
            `;
            const list = await this.articlesEntity.query(sql);
            list.map(item => {
                item.images = item.images.length ? item.images.split(',') : [];
                item.tags = item.tags.split(',');
                item.createTime = new Date(item.createTime).getTime();
                item.likesAvatar = item.likesAvatar ? item.likesAvatar.split(',') : [];
                return item;
            });
            return {
                success: true,
                message: '查询成功',
                data: list
            }
        } catch (error) {
            console.log(error);
            throw new CoolCommException('查询失败');
        }
    }

    /**
     * 个人文章列表
     * @param userId 用户id
     * @param page 页码
     * @param size 条数
     */
    async userList(userId, page, size) {
        try {
            const sql = `
            SELECT
            a.*,
            u.avatar,
            u.nickname,
            u.sex,
            GROUP_CONCAT( d.name ) AS tags,
            (
                SELECT
                    COUNT( * )
                FROM
                    app_article_likes al
                WHERE
                    al.articleId = a.id
            ) AS likes,
            (
                SELECT
                    GROUP_CONCAT( u.avatar )
                FROM
                    app_article_likes al
                    LEFT JOIN app_user u ON al.userId = u.id
                WHERE
                    al.articleId = a.id
                ORDER BY
                    al.createTime DESC
                LIMIT 4
            ) AS likesAvatar,
            (
                SELECT
                    COUNT( * )
                FROM
                    app_comments ac
                WHERE
                    ac.articleId = a.id
            ) AS comments
            FROM
                app_articles a
                LEFT JOIN app_user u ON a.userId = u.id
                LEFT JOIN dict_info d ON FIND_IN_SET( d.id, a.tagIds )
            WHERE
                a.userId = ${userId}
                AND a.status = 1
            GROUP BY
                a.id
            ORDER BY
                a.createTime DESC
            LIMIT ${(page - 1) * size}, ${size}
            `;
            const list = await this.articlesEntity.query(sql);
            const { avatar, nickname } = await this.userEntity.findOne({ where: { id: userId } });
            list.map(item => {
                item.images = item.images.length ? item.images.split(',') : [];
                item.tags = item.tags.split(',');
                item.createTime = new Date(item.createTime).getTime();
                item.likesAvatar = item.likesAvatar ? item.likesAvatar.split(',') : [];
                return item;
            });
            return {
                success: true,
                message: '查询成功',
                data: {
                    list,
                    avatar,
                    nickname
                }
            }
        } catch (error) {
            console.log(error);
            throw new CoolCommException('查询失败');
        }
    }

    /**
     * 文章详情
     * @param id 文章id
     */
    async detail(id) {
        try {
            await this.articlesEntity.increment({ id }, 'views', +1);
            const sql = `
                SELECT
                a.*,
                u.avatar,
                u.nickname,
                u.sex,
                GROUP_CONCAT( d.name ) AS tags,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_article_likes al
                    WHERE
                        al.articleId = a.id
                ) AS likes,
                (
                    SELECT
                        GROUP_CONCAT( u.avatar )
                    FROM
                        app_article_likes al
                        LEFT JOIN app_user u ON al.userId = u.id
                    WHERE
                        al.articleId = a.id
                    ORDER BY
                        al.createTime DESC
                    LIMIT 4
                ) AS likesAvatar,
                (
                    SELECT
                        COUNT( * )
                    FROM
                        app_comments ac
                    WHERE
                        ac.articleId = a.id
                ) AS comments
            FROM
                app_articles a
                LEFT JOIN app_user u ON a.userId = u.id
                LEFT JOIN dict_info d ON FIND_IN_SET( d.id, a.tagIds )
            WHERE
                a.id = ${id}
            GROUP BY
                a.id
            ORDER BY
                a.createTime DESC
            `;
            const detail = await this.articlesEntity.query(sql);
            detail.map(item => {
                item.images = item.images.length ? item.images.split(',') : [];
                item.tags = item.tags.split(',');
                item.createTime = new Date(item.createTime).getTime();
                item.likesAvatar = item.likesAvatar ? item.likesAvatar.split(',') : [];
                return item;
            });
            return {
                success: true,
                message: '查询成功',
                data: detail[0]
            }
        } catch (error) {
            console.log(error);
            throw new CoolCommException('查询失败');
        }
    }

    /**
     * 文章点赞
     * @param id 文章id
     */
    async like(id) {
        try {
            const likes = await this.articleLikesEntity.findOne({
                where: { articleId: id, userId: this.ctx.user.userId }
            });
            likes ? await this.articleLikesEntity.delete({ articleId: id, userId: this.ctx.user.userId }) : await this.articleLikesEntity.save({ articleId: id, userId: this.ctx.user.userId });
            const sql = `
                SELECT
                    COUNT( * ) AS likes,
                    (
                        SELECT
                            GROUP_CONCAT( u.avatar )
                        FROM
                            app_article_likes al
                            LEFT JOIN app_user u ON al.userId = u.id
                        WHERE
                            al.articleId = ${id}
                        ORDER BY
                            al.createTime DESC
                        LIMIT 4
                    ) AS avatars
                FROM
                    app_article_likes al
                WHERE
                    al.articleId = ${id}
            `;
            const likesInfo = await this.articleLikesEntity.query(sql);
            likesInfo[0].avatars = likesInfo[0].avatars ? likesInfo[0].avatars.includes(',') ? likesInfo[0].avatars.split(',') : [likesInfo[0].avatars] : [];
            return {
                success: true,
                message: likes ? '取消点赞' : '点赞成功',
                data: likesInfo[0]
            }
        } catch (error) {
            throw new CoolCommException('操作失败');
        }
    }

    /**
     * 文章评论
     * @param id 文章id
     * @param content 评论内容
     */
    async comment(id, content) {
        try {
            const comment = await this.commentsEntity.save({ articleId: id, content, userId: this.ctx.user.userId });
            if (comment) {
                return {
                    success: true,
                    message: '评论成功',
                    data: null
                }
            }
            return {
                success: false,
                message: '评论失败',
                data: null
            }
        } catch (error) {
            throw new CoolCommException('评论失败');
        }
    }

    /**
     * 回复评论
     * @param toUserId 回复用户id
     * @param pid 父id
     * @param content 评论内容
     */
    async reply(toUserId, pid, content) {
        try {
            const comment = await this.commentsEntity.save({ toUserId, pid, content, userId: this.ctx.user.userId });
            if (comment) {
                return {
                    success: true,
                    message: '回复成功',
                    data: null
                }
            }
            return {
                success: false,
                message: '回复失败',
                data: null
            }
        } catch (error) {
            throw new CoolCommException('回复失败');
        }
    }

    /**
     * 文章评论列表
     * @param id 文章id
     */
    async commentList(id) {
        try {
            const sql = `
                SELECT
                ac.*,
                u.avatar,
                u.nickname,
                tu.avatar AS toAvatar,
                tu.nickname AS toNickname,
                (
                    SELECT
                        JSON_ARRAYAGG(
                            JSON_OBJECT(
                                'id',
                                ac2.id,
                                'pid',
                                ac2.pid,
                                'userId',
                                ac2.userId,
                                'nickname',
                                u2.nickname,
                                'toUserId',
                                ac2.toUserId,
                                'toNickname',
                                u3.nickname,
                                'content',
                                ac2.content,
                                'createTime',
                                ac2.createTime
                            )
                        )
                    FROM
                        app_comments ac2
                        LEFT JOIN app_user u2 ON ac2.userId = u2.id
                        LEFT JOIN app_user u3 ON ac2.toUserId = u3.id
                    WHERE
                        ac2.pid = ac.id
                    GROUP BY
                        ac2.pid
                ) AS children
            FROM
                app_comments ac
                LEFT JOIN app_user u ON ac.userId = u.id
                LEFT JOIN app_user tu ON ac.toUserId = tu.id
            WHERE
                ac.articleId = ${id}
            ORDER BY
                ac.createTime DESC
            `;
            const list = await this.commentsEntity.query(sql);
            list.map(item => {
                item.createTime = new Date(item.createTime).getTime();
                item.children = item.children ? item.children.map(child => { child.createTime = new Date(child.createTime).getTime(); return child; }) : [];
                return item;
            });
            return {
                success: true,
                message: '查询成功',
                data: list
            }
        } catch (error) {
            throw new CoolCommException('查询失败');
        }
    }
}
